﻿using Abp.Events.Bus;
using Abp.Runtime.Caching;
using NetCore.Events;
using System;
using System.Threading.Tasks;

namespace NetCore.Locks
{
    /// <summary>
    /// 默认业务锁
    /// </summary>
    public class DefaultLock: ILock
    {
        /// <summary>
        /// 锁定标识 唯一
        /// </summary>
        private string _key;
        /// <summary>
        /// redis缓存
        /// </summary>
        private readonly ICache _cache;
        public IEventBus EventBus { get; set; }

        /// <summary>
        /// 初始化业务锁
        /// </summary>
        /// <param name="cacheManager">缓存</param>
        public DefaultLock(ICacheManager cacheManager)
        {
            _cache = cacheManager.GetCache(NetCoreConsts.UserLocker);
            EventBus = NullEventBus.Instance;
        }

        #region 异步方法

        /// <summary>
        /// 锁定，成功锁定返回true，false代表之前已被锁定
        /// </summary>
        /// <param name="key">锁定标识</param>
        /// <param name="expiration">锁定时间间隔</param>
        /// <returns></returns>
        public async Task<bool> LockAsync(string key, TimeSpan? expiration = null)
        {
            _key = key;
            if (await _cache.GetOrDefaultAsync(key) != null) return false;
            await _cache.SetAsync(key, 1, expiration);
            return true;
        }
        /// <summary>
        /// 解除锁定
        /// </summary>
        public async Task UnLockAsync()
        {
            await _cache.RemoveAsync(_key);
            //用remove事件去处理
            await EventBus.TriggerAsync(new RemoveCacheEvent(NetCoreConsts.UserLocker,_key));
        }

        #endregion

        #region 同步方法

        /// <summary>   
        /// 锁定，成功锁定返回true，false代表之前已被锁定
        /// </summary>
        /// <param name="key">锁定标识</param>
        /// <param name="expiration">锁定时间间隔</param>
        /// <returns></returns>
        public bool Lock(string key, TimeSpan? expiration = null)
        {
            _key = key;
            if (_cache.GetOrDefault(key) != null) return false;
             _cache.Set(key, 1, expiration);
            return true;
        }
        /// <summary>
        /// 解除锁定
        /// </summary>
        public void UnLock()
        {
            //1、通过Icache去处理
            _cache.Remove(_key);
            
            //也可以使用remove事件去处理
            //EventBus.Trigger(new RemoveCacheEvent(NetCoreConsts.UserLocker,_key));
        }

        #endregion
    }
}
